//
//  XYMeetingViewController.m
//  NemoSDKDemo
//
//  Created by 高超 on 2020/7/30.
//  Copyright © 2020 JackYang. All rights reserved.
//

#import "XYMeetingViewController.h"
#import "UIColor+XYColor.h"
#import "XYCallingTopToolBarView.h"
#import "XYCallingBottomToolBarView.h"
#import "PulldownMenu.h"
#import "NemoKeyBoard_InTalking.h"
#import "WebViewController.h"
#import "XYShareView.h"
#import "StatsInfoViewController.h"
#import "StatsViewController.h"
#import "ConnectingView.h"
#import "XYVideoContainerCell.h"
#import "XYCustomVideoView.h"
#import "NemoWhiteboardView.h"
#import "XYFECCView.h"
#import "DanmakuLabel.h"
#import "SEXylinkBottomToolBarView.h"

@interface XYMeetingViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,WhiteboardDelegate>

@property (nonatomic, strong) SEXylinkBottomToolBarView *customToolBarView;

@property (nonatomic, strong) XYCallingBottomToolBarView *bottomToolBarView;

@property (nonatomic, strong) XYCallingTopToolBarView *topToolBarView;

@property (nonatomic, strong) PulldownMenu *menu;

@property (nonatomic, strong) NemoRecordingStateView *recordingView;


@property (nonatomic, strong) XYShareView *shareView;

@property (nonatomic, strong) NemoWhiteboardView *whiteboardView;

@property (nonatomic, assign) NemoWhiteBoardSharingState whiteBoardSharingState;

@property (nonatomic, strong) XYFECCView *feccView;

@property (nonatomic, strong) UIImage *shareImage;

@property (nonatomic, assign) BJMuteActionType muteActionType;

@property (nonatomic, strong) UIButton *muteButton;

@property (nonatomic, strong) NemoConfMgmtInfo *confMgmtInfo;

@property (nonatomic, assign) BOOL isHandupNow;

@property (nonatomic, strong) UIButton *switchCameraBtn;

@property (nonatomic, assign) BOOL audioOnlyMode;

@property (nonatomic, assign) BOOL videoMuteWhenAudioOnlyMode;

@property (nonatomic, assign) BOOL firstIn;

@property (nonatomic, strong) ConnectingView *connectingView;

@property (nonatomic, strong) UIPageControl *pageControl;

@property (nonatomic, strong) UICollectionView *collectionView;

@property (nonatomic, strong) NSMutableDictionary *dataSource;

@property (nonatomic, strong) UICollectionViewFlowLayout *flowLayout;

@property (nonatomic, assign) NSInteger currentPage;

@property (nonatomic, assign) NSInteger allPage;

@property (nonatomic, strong) NemoRosters *rosters;

@property (nonatomic, strong) NemoLayout *localLayout;

@property (nonatomic, strong) NemoCaptionInfoModel *captionInfoModel;

@property (nonatomic, assign) NemoDualState dualState;

@property (nonatomic, assign) NemoRecordingType recordingType;

@end

@implementation XYMeetingViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
    self.automaticallyAdjustsScrollViewInsets = NO;
    _firstIn = YES;

    self.pageControl = [[UIPageControl alloc] init];
    self.pageControl.hidden = YES;
    
    _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:self.flowLayout];
    _collectionView.backgroundColor = [UIColor clearColor];
    _collectionView.delegate = self;
    _collectionView.dataSource = self;
    _collectionView.pagingEnabled = YES;
    _collectionView.scrollEnabled = NO;
    _collectionView.bounces = NO;
#if __clang_major__ > 10
    if (@available(iOS 11.0, *)) {
#else
    if ([UIDevice currentDevice].systemVersion.floatValue >= 11) {
#endif
        _collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    //非对称布局，第1页
    [_collectionView registerClass:[XYVideoContainerCell class] forCellWithReuseIdentifier:@"AsymmetryrCell"];
    //对称布局，第2页以后
    [_collectionView registerClass:[XYVideoContainerCell class] forCellWithReuseIdentifier:@"SymmetryrCell"];
    [self.view addSubview:_collectionView];
    
    _dataSource = [[NSMutableDictionary alloc] init];
    
    _localLayout = [[NemoLayout alloc] init];
    _localLayout.layoutState = NemoStreamState_Received;
    _localLayout.remoteName = [XYSDKManager sharedInstance].user.displayName;
    [_dataSource setObject:[NSMutableArray arrayWithArray:@[_localLayout]] forKey:@(0)];
    _allPage = 1;
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_statusBarOrientationChange) name:UIApplicationDidChangeStatusBarOrientationNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showAndHideToolBar) name:@"whiteboard_tap" object:nil];
    
    self.connectingView = [[ConnectingView alloc] initWithFrame:self.view.bounds];
//    self.connectingView.displayNameLabel.text = [XYSDKManager sharedInstance].meetingNumber;
    self.connectingView.displayNameLabel.text = self.displayName;
    [self.view addSubview:self.connectingView];
    __weak typeof(self)weakSelf = self;
    self.connectingView.hangup = ^{
        [[XYSDKManager sharedInstance] leaveMeeting];
        [weakSelf.connectingView removeFromSuperview];
        weakSelf.connectingView = nil;
        [weakSelf dismissViewControllerAnimated:YES completion:nil];
    };
    self.connectingView.accept = ^{
        [[XYSDKManager sharedInstance] acceptMeeting];
        [weakSelf.connectingView removeFromSuperview];
        weakSelf.connectingView = nil;
    };
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    [self.topToolBarView startMeetingTimer];
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
    [self.topToolBarView stopMeetingTimer];
}

#pragma mark private function
- (void)_setupSubView {
    self.view.backgroundColor = [UIColor colorWithHexString:@"#22222B"];
    [self.view addSubview:self.customToolBarView];
    [self.customToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.view);
        make.bottom.mas_equalTo(-UIApplication.sharedApplication.keyWindow.safeAreaInsets.bottom);
        make.height.mas_equalTo(214);
    }];
//    [self.view addSubview:self.topToolBarView];
//    [self.topToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.left.top.right.equalTo(self.view);
//        if ([self _isFullScreen]) {
//            make.height.mas_equalTo(88);
//        }else{
//            make.height.mas_equalTo(66);
//        }
//    }];
//
//    [self.view addSubview:self.bottomToolBarView];
//    [self.bottomToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.left.bottom.right.equalTo(self.view);
//        if ([self _isFullScreen]) {
//            make.height.mas_equalTo(72);
//        }else{
//            make.height.mas_equalTo(52);
//        }
//    }];
//
//    self.switchCameraBtn = [UIButton buttonWithType:UIButtonTypeCustom];
//    [self.switchCameraBtn setImage:[UIImage imageNamed:@"switchCamera"] forState:UIControlStateNormal];
//    [self.switchCameraBtn setTitle:@"切换摄像头" forState:UIControlStateNormal];
//    [self.switchCameraBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
//    self.switchCameraBtn.titleLabel.font = [UIFont systemFontOfSize:10];
//    [self.switchCameraBtn addTarget:self action:@selector(switchCamera:) forControlEvents:UIControlEventTouchUpInside];
//    [self.view addSubview:self.switchCameraBtn];
//    [self.switchCameraBtn mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.left.mas_equalTo(10);
//        make.top.equalTo(self.topToolBarView.mas_bottom).offset(10);
//        make.width.mas_equalTo(65);
//        make.height.mas_equalTo(65);
//    }];
//    [self.switchCameraBtn setTitleEdgeInsets:UIEdgeInsetsMake(55, -45, 0, 0)];
//    [self.switchCameraBtn setImageEdgeInsets:UIEdgeInsetsMake(-15, 9, 0, 0)];
//
//    [self refreshFeccView];
//
//    self.pageControl.frame = CGRectMake(0, [self _isFullScreen]?42:20, 200, 20);
//    self.pageControl.xy_x = (kScreen.width-200)/2;
//    [self.view insertSubview:self.pageControl aboveSubview:_collectionView];
}


- (BOOL)_isFullScreen {
#if __clang_major__ > 10
    if (@available(iOS 11.0, *)) {
#else
    if ([UIDevice currentDevice].systemVersion.floatValue >= 11) {
#endif
        CGFloat height = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom;
        return (height > 0);
    } else {
        return NO;
    }
}

- (void)_statusBarOrientationChange {
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (orientation ==UIInterfaceOrientationLandscapeLeft)
    {
        _orientation = NemoVideoOrientation_LandscapeLeft;
        [[XYSDKManager sharedInstance] changeOrientation:NemoVideoOrientation_LandscapeLeft];
    }
    if (orientation == UIInterfaceOrientationLandscapeRight)
    {
        _orientation = NemoVideoOrientation_LandscapeRight;
        [[XYSDKManager sharedInstance] changeOrientation:NemoVideoOrientation_LandscapeRight];
    }
    if (orientation == UIInterfaceOrientationPortrait)
    {
        _orientation = NemoVideoOrientation_Portrait;
        [[XYSDKManager sharedInstance] changeOrientation:NemoVideoOrientation_Portrait];
    }
    [self _relayoutSubview];
    [self dismissMenuView];
}

- (void)_relayoutSubview {
    if (_orientation == NemoVideoOrientation_Portrait) {
        if ([self _isFullScreen]) {
            [self.topToolBarView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.height.mas_equalTo(88);
            }];
            self.pageControl.xy_y = 42;
        }else {
            [self.topToolBarView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.height.mas_equalTo(66);
            }];
            self.pageControl.xy_y = 20;
        }
        [self.switchCameraBtn mas_updateConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(10);
        }];
        [_recordingView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.topToolBarView.mas_bottom).with.offset(-10);
        }];
    }else {
        [self.topToolBarView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo(66);
        }];
        [self.switchCameraBtn mas_updateConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(40);
        }];
        self.pageControl.xy_y = 20;
        [_recordingView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.topToolBarView.mas_bottom).with.offset(-32);
        }];
    }
    
    UIView *noticeContainer = self.view;
    NSInteger tag = 1000121;
    DanmakuLabel *danmakuLabel = [noticeContainer viewWithTag:tag];
    if (danmakuLabel != nil) {
        [danmakuLabel updateDanmakuLayoutInView:noticeContainer size:danmakuLabel.frame.size];
    }
    if (self.captionInfoModel && self.captionInfoModel.display && (self.captionInfoModel.location == NemoCaptionLocationTop)) {
        tag = 1000122;
        UILabel * danmakuFixedLabel = [noticeContainer viewWithTag:tag];
        [danmakuFixedLabel mas_updateConstraints:^(MASConstraintMaker *make) {
            if (kScreen.width < kScreen.height) {
                make.top.equalTo(self.view.mas_top).offset([self _isFullScreen] ? 34:0);
            }else{
                make.top.equalTo(self.view.mas_top).offset(0);
            }
        }];
        tag = 1000123;
        UIView * bView = [noticeContainer viewWithTag:tag];
        [bView mas_updateConstraints:^(MASConstraintMaker *make) {
            if (kScreen.width < kScreen.height) {
                make.top.equalTo(self.view.mas_top).offset([self _isFullScreen] ? 34:0);
            }else{
                make.top.equalTo(self.view.mas_top).offset(0);
            }
        }];
    }
    
    _collectionView.frame = CGRectMake(0, 0, kScreen.width, kScreen.height);
    _flowLayout = nil;
    _collectionView.collectionViewLayout = self.flowLayout;
    [_collectionView setContentOffset:CGPointMake(kScreen.width*_currentPage, 0) animated:NO];
    
    _feccView.updateFrame(_orientation == NemoVideoOrientation_Portrait);
}

- (void)_reloadCurrentPageCell {
    //刷新ui
    XYVideoContainerCell *cell = (XYVideoContainerCell *)[_collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:_currentPage inSection:0]];
    [cell updateVideos:[_dataSource objectForKey:@(_currentPage)] index:_currentPage activeSpeakerId:_rosters.activeSpeakerPid];
    [self refreshFeccView];
}

- (NemoLayout *)_focusLayout {
    NSArray *array = [_dataSource objectForKey:@(0)];
    NemoLayout *layout = nil;
    if (array.count > 1) {
        layout = array[1];
    }
    return layout;
}

- (void)_updateParticipantCount:(NemoRosters *)rosters {
    NSMutableSet *people = [NSMutableSet setWithArray:rosters.peopleRosters];
    NSSet *content = [NSSet setWithArray:rosters.contentRosters];
    [people unionSet:content];
    [self.bottomToolBarView updateParticipantsNum:people.count + 1];
}

#pragma mark Public Function
- (void)setOrientation:(NemoVideoOrientation)orientation {
    _orientation = orientation;
    UIDeviceOrientation toOrientation = UIDeviceOrientationPortrait;
    if (orientation == NemoVideoOrientation_LandscapeLeft ||
        orientation == NemoVideoOrientation_LandscapeRight) {
        toOrientation = UIDeviceOrientationLandscapeLeft;
    }
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:toOrientation] forKey:@"orientation"];
}

- (void)meetingState:(NemoCallState)state {
    //呼叫状态
    if (state == NemoCallState_Connecting) {
        [[XYSDKManager sharedInstance] setLocalMicMute:[XYSDKManager sharedInstance].muteAudio];
        [self setLocalMicMute:[XYSDKManager sharedInstance].muteAudio];
        
        [[XYSDKManager sharedInstance] setLocalVideoMute:[XYSDKManager sharedInstance].muteVideo];
        [self setLocalVideoMute:[XYSDKManager sharedInstance].muteVideo];
        
    }else if (state == NemoCallState_Connected) {
        if (self.connectingView) {
            [self.connectingView removeFromSuperview];
            self.connectingView = nil;
        }
        [self _setupSubView];
        [[XYSDKManager sharedInstance] setSpeakerphoneOn:NO];
        BOOL mute = [XYSDKManager sharedInstance].isLocalMicMuted;
        if (mute) {
            [[XYSDKManager sharedInstance] setLocalMicMute:YES];
            [self setLocalMicMute:YES];
        }
        [self.topToolBarView updateMeetingRoomNum:[XYSDKManager sharedInstance].meetingNumber];
    }else if (state == NemoCallState_DisConnected) {
        if (self.orientation != NemoVideoOrientation_Portrait) {
            self.orientation = NemoVideoOrientation_Portrait;
        }
        [XYLayoutManager sharedInstance].whiteboardState = XYWhiteboardState_Stop;
        if ([self.presentedViewController isKindOfClass:[WebViewController class]]) {
            [self dismissViewControllerAnimated:YES completion:nil];
        }
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

- (void)meetingControlChanged:(NemoConferenceManagerManagementType)type confMgmtInfo:(NemoConfMgmtInfo *)info {
    //会控回调
    self.confMgmtInfo = info;
    if (type == NemoConferenceManagerManagementType_Mute ||
        type == NemoConferenceManagerManagementType_MuteMandatory) {
        [[XYSDKManager sharedInstance] setLocalMicMute:YES];
        [self setLocalMicMute:YES];
    }else if (type == NemoConferenceManagerManagementType_Unmute ||
              type == NemoConferenceManagerManagementType_UnmuteTemporary) {
        if (_firstIn) {
            _firstIn = NO;
            [[XYSDKManager sharedInstance] setLocalMicMute:[XYSDKManager sharedInstance].muteAudio];
            [self setLocalMicMute:[XYSDKManager sharedInstance].muteAudio];
        }else {
            [[XYSDKManager sharedInstance] setLocalMicMute:NO];
            [self setLocalMicMute:NO];
        }
    }
    _isHandupNow = NO;
    [self refreshMuteMicBtn];
}

- (void)whiteboardStateChanged:(NemoWhiteboardRemoteState)state {
    [self showAndHideToolBar];
    if (state == NemoWhiteboardRemoteState_Stop || state == NemoWhiteboardRemoteState_Error) {
//        self.orientation = NemoVideoOrientation_Portrait;
        [[XYSDKManager sharedInstance] stopWhiteboard];
        [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:0];
        self.whiteBoardSharingState = NemoWhiteBoardSharingStateNotSet;
        if (self.whiteboardView) {
            [self.whiteboardView removeFromSuperview];
        }
        self.whiteboardView = nil;
        [self.bottomToolBarView updateShareItemStatus:NO];
    }else if (state == NemoWhiteboardRemoteState_Start) {
        if (self.whiteBoardSharingState == NemoWhiteBoardSharingStateNotSet) {
            self.orientation = NemoVideoOrientation_LandscapeLeft;
            [self onWhiteboard];
            self.whiteBoardSharingState = NemoWhiteBoardSharingStateRemote;
        }
    }
}

- (void)contentShareStateChanged:(NemoShareContentType)type state:(NemoShareContentState)state {
    [self.bottomToolBarView updateShareItemStatus:state==NemoShareContentState_Start];
    if (type == NemoShareContentType_Image) {
        if (state == NemoShareContentState_Start) {
            self.shareView = [[XYShareView alloc] initWithFrame:self.view.bounds];
            [self.view addSubview:self.shareView];
            self.shareView.type = XYShareViewTypeImage;
            [self.shareView setImage:self.shareImage];
            [self.view insertSubview:self.shareView belowSubview:self.topToolBarView];
        }else {
            [self.shareView removeFromSuperview];
            self.shareView = nil;
        }
    }else if (type == NemoShareContentType_Screen) {
        if (state == NemoShareContentState_Start) {
            self.shareView = [[XYShareView alloc] initWithFrame:self.view.bounds];
            [self.view addSubview:self.shareView];
            self.shareView.type = XYShareViewTypeScreen;
            [self.view insertSubview:self.shareView belowSubview:self.topToolBarView];
        }else {
            [self.shareView removeFromSuperview];
            self.shareView = nil;
        }
    }
}

- (void)videoViewLayout:(NSArray *)videosInfo {
    //组装数据源
    NSLog(@"%s - %lu", __FUNCTION__, (unsigned long)videosInfo.count);
    NSMutableArray *array = [NSMutableArray arrayWithArray:videosInfo];
    if (_currentPage < 2) {
        //第1、2页加入local
        if (array.count) {
            if (_rosters.contentSenderPid == 0) {
                //没有content，前两页数据共用
                [array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                    NemoLayout *layout = (NemoLayout *)obj;
                    if (layout.isContent) {
                        [array removeObject:obj];
                        *stop = YES;
                    }
                }];
                [array insertObject:_localLayout atIndex:0];
                [_dataSource setObject:array forKey:@(0)];
                [_dataSource setObject:array forKey:@(1)];
            }else {
                if (_currentPage == 0) {
                    [_dataSource setObject:array forKey:@(0)];
                }else {
                    [array insertObject:_localLayout atIndex:0];
                    [_dataSource setObject:array forKey:@(1)];
                }
            }
        }else {
            //没有参会者，则加入local
            [_dataSource removeAllObjects];
            [array insertObject:_localLayout atIndex:0];
            [_dataSource setObject:array forKey:@(0)];
        }
        if (array.count > 6) {
            //第2页最多显示1+5
            NSArray *arr = [array copy];
            [_dataSource setObject:[arr subarrayWithRange:NSMakeRange(0, 6)] forKey:@(1)];
        }
    }else {
        [_dataSource setObject:array forKey:@(_currentPage)];
    }
    
    [self _reloadCurrentPageCell];
}

- (void)rosterChanged:(NemoRosters *)rosters {
    [self _updateParticipantCount:rosters];
    
    NSInteger peopleCount = rosters.peopleRosters.count;
    NSInteger updateAllPage = 0;
    if (peopleCount == 0) {
        [_dataSource removeAllObjects];
        [_dataSource setObject:@[_localLayout] forKey:@(0)];
        updateAllPage = 1;
    }else {
        //计算页数
        //显示规则：第1页，1个local+6个remote   第1页是非对称布局
        //        第2页，1个local+5个remote   第2页开始是对称布局，每页6个，第2页含有local
        //        第3页，6个remote            第3页开始不显示local
        if (peopleCount <= 5) {
            //2页,第1页6个，第2页5个  不包含local
            updateAllPage = 2;
        }else {
            if ((peopleCount-5)%6) {
                //第3页开始，最后一页不足6个，多+1页
                updateAllPage = (peopleCount-5)/6+1;
            }else {
                //第3页开始，最后一页刚好6个
                updateAllPage = (peopleCount-5)/6;
            }
            //加上前两页
            updateAllPage += 2;
        }
    }
    
    self.pageControl.numberOfPages = updateAllPage;
    self.pageControl.hidden = updateAllPage==1;
    if (_allPage != updateAllPage) {
        _allPage = updateAllPage;
        [_collectionView reloadData];
    }
    
    if (rosters.peopleRosters.count == 0) {
        return;
    }
    
    //判断当前页视频是否有变化
    NSArray *currentLayouts = [_dataSource objectForKey:@(_currentPage)];
    NSArray *newRosters = nil;
    if (_currentPage < 2) {
        //前两页因为插入了local，所以下标单独处理
        NSInteger length = _currentPage?5:6;
        if (rosters.peopleRosters.count < length) {
            length = rosters.peopleRosters.count;
        }
        //length：防止取值越界
        newRosters = [rosters.peopleRosters subarrayWithRange:NSMakeRange(0, length)];
    }else {
        NSInteger length = 6;
        if (rosters.peopleRosters.count < (_currentPage-1)*length-1+length) {
            length = rosters.peopleRosters.count - ((_currentPage-2)*length-1+length);
        }
        //length：防止取值越界
        newRosters = [rosters.peopleRosters subarrayWithRange:NSMakeRange((_currentPage-1)*6-1, length)];
    }
    
    BOOL needUpdate = NO;
    if (currentLayouts.count != newRosters.count) {
        if (_currentPage < 2) {
            if (currentLayouts.count-1 != newRosters.count) {
                //当前页视频发生变化
                needUpdate = YES;
            }
        }else {
            //当前页视频发生变化
            needUpdate = YES;
        }
    }else {
        for (NSInteger i = 0; i < currentLayouts.count; i++) {
            NemoLayout *currLayout = currentLayouts[i];
            NemoRosterInfo *newRoster = newRosters[i];
            if (![currLayout.participantId isEqualToString:[NSString stringWithFormat:@"%d",newRoster.participantId]]) {
                //当前页视频发生变化
                needUpdate = YES;
                break;
            }
        }
    }
    
    if (_rosters.contentSenderPid != rosters.contentSenderPid && _currentPage == 0) {
        //有content变化
        needUpdate = YES;
    }
    
    if (rosters.activeSpeakerPid && _rosters.activeSpeakerPid != rosters.activeSpeakerPid && _currentPage == 0) {
        //as变化
        needUpdate = YES;
    }
    
    if (needUpdate) {
        //当前页面需要更新
        [[XYLayoutManager sharedInstance] customLayout:rosters indexPage:_currentPage];
    }
    if (_currentPage == _allPage) {
        _currentPage -= 1;
        [[XYLayoutManager sharedInstance] customLayout:rosters indexPage:_currentPage];
    }
    
    _rosters = rosters;
}

- (void)recieveCaption:(NemoCaptionInfoModel *)model {
    self.captionInfoModel = model;
    UIView *noticeContainer = self.view;
    NSInteger tag = 1000121;
    DanmakuLabel *danmakuLabel = [noticeContainer viewWithTag:tag];
    if (danmakuLabel)
    {
        [danmakuLabel stop];
    }
    tag = 1000122;
    UILabel * danmakuFixedLabel = [noticeContainer viewWithTag:tag];
    if (danmakuFixedLabel) {
        [danmakuFixedLabel removeFromSuperview];
    }
    tag = 1000123;
    UIView * bView = [noticeContainer viewWithTag:tag];
    if (bView) {
        [bView removeFromSuperview];
    }
    if (!model.display)return;
    
    CGFloat height = 44;
    if (model.fontType == NemoCaptionFontSizeSmall) {
        height = 36;
    }else if (model.fontType == NemoCaptionFontSizeBig){
        height = 48;
    }
    
    if (model.scroll) {
        UIView * bottomView = [[UIView alloc] init];
        bottomView.backgroundColor = [UIColor colorWithHexString:model.bgColor withAlpha:model.bgColorAlpha];
        bottomView.userInteractionEnabled = NO;
        bottomView.tag = 1000123;
        [noticeContainer addSubview:bottomView];
        [self.view insertSubview:bottomView aboveSubview:_collectionView];
        
        DanmakuConfigure *configure = [[DanmakuConfigure alloc] init];
        configure.captionModel = model;
        configure.location = (DanmakuLocation)(model.location % 3);
        danmakuLabel = [DanmakuLabel createDanmakuLabelWithConfig:configure inView:noticeContainer delegate:nil];
        danmakuLabel.tag = 1000121;
        danmakuLabel.userInteractionEnabled = NO;
        [self.view insertSubview:danmakuLabel aboveSubview:bottomView];
        [danmakuLabel start];
        if (danmakuLabel.frame.size.height > height) {
            height = danmakuLabel.frame.size.height;
        }
        if (model.location == NemoCaptionLocationTop){
            [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                if (kScreen.width < kScreen.height) {
                    make.top.equalTo(self.view.mas_top).offset([self _isFullScreen] ? 34:0);
                }else{
                    make.top.equalTo(self.view.mas_top).offset(0);
                }
                make.height.mas_equalTo(height);
            }];
        } else if (model.location == NemoCaptionLocationMiddle){
            [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                make.center.equalTo(self.view);
                make.height.mas_equalTo(height);
            }];
        } else{
            [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                make.bottom.equalTo(self.view.mas_bottom).offset(0);
                make.height.mas_equalTo(height);
            }];
        }
    }else{
        danmakuFixedLabel = [[UILabel alloc] init];
        danmakuFixedLabel.tag = 1000122;
        danmakuFixedLabel.backgroundColor = [UIColor colorWithHexString:model.bgColor withAlpha:model.bgColorAlpha];
        CGFloat font = 0;
        if (model.fontType == NemoCaptionFontSizeSmall) {
            font = 17;
        }else if (model.fontType == NemoCaptionFontSizeMiddle) {
            font = 21;
        }else {
            font = 25;
        }
        danmakuFixedLabel.font = [UIFont systemFontOfSize:font];
        danmakuFixedLabel.textColor = [UIColor colorWithHexString:model.fontColor];
        if (model.bgColorAlpha== 0) {
            danmakuFixedLabel.shadowColor = [UIColor colorWithWhite:0 alpha:0.8];
        }else{
            danmakuFixedLabel.shadowColor = [UIColor clearColor];
        }
        danmakuFixedLabel.textAlignment = NSTextAlignmentCenter;
        danmakuFixedLabel.numberOfLines = 0;
        [self.view addSubview:danmakuFixedLabel];
        [self.view insertSubview:danmakuFixedLabel aboveSubview:_collectionView];

        if (model.location == NemoCaptionLocationTop){
            [danmakuFixedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                if (kScreen.width < kScreen.height) {
                    make.top.equalTo(self.view.mas_top).offset([self _isFullScreen] ? 34:0);
                }else{
                    make.top.equalTo(self.view.mas_top).offset(0);
                }
                make.height.mas_equalTo(height);
            }];
        } else if (model.location == NemoCaptionLocationMiddle){
            [danmakuFixedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                make.center.equalTo(self.view);
                make.height.mas_equalTo(height);
            }];
        }else{
            [danmakuFixedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.right.equalTo(self.view);
                make.bottom.equalTo(self.view.mas_bottom).offset(0);
                make.height.mas_equalTo(height);
            }];
        }
        danmakuFixedLabel.text = model.content;
    }
}

- (void)dualStreamStateChanged:(NemoDualState)state reason:(NSString *)reason {
    if (self.dualState == NemoDualState_Sending && state == NemoDualState_Idle) {
        [[XYSDKManager sharedInstance] stopContentSharing];
    }
    self.dualState = state;
}

- (void)recordingStateChanged:(BOOL)start {
    self.recordingType = start?NemoRecordingTypeByOthers:NemoRecordingTypeStopByOthers;
    [self recordingState:start];
}

#pragma mark common func
- (void)onKeyBoardInTaking{
    NemoKeyBoard_InTalking *keyboard = [NemoKeyBoard_InTalking showNemoKeyBoard_InTalking].result(^(NSString *result){
        [[XYSDKManager sharedInstance] dialDtmfWithfullScreenLayout:[self _focusLayout] content:result];
    });
    [self.view addSubview:keyboard];
    [self.view bringSubviewToFront:keyboard];
    
    [self showAndHideToolBar];
}

- (void)onSwitchTorch {
    if ([[XYSDKManager sharedInstance] torchMode] == NemoTorchMode_on) {
        [[XYSDKManager sharedInstance] switchTorchMode:NemoTorchMode_off];
    }else {
        [[XYSDKManager sharedInstance] switchTorchMode:NemoTorchMode_on];
    }
}

- (void)onAudioMode {
    _audioOnlyMode = !_audioOnlyMode;
    [self.bottomToolBarView updateItemWithEnableStatus:!_audioOnlyMode itemType:XYBottomToolBarItemTypeVideoMute];
    [[XYSDKManager sharedInstance] enableAudioMode:_audioOnlyMode];
    if (_audioOnlyMode) {
        [[XYSDKManager sharedInstance] setLocalVideoMute:YES];
        _localLayout.layoutState = _audioOnlyMode?NemoStreamState_AudioOnly:NemoStreamState_Received;
    }else {
        [[XYSDKManager sharedInstance] setLocalVideoMute:_videoMuteWhenAudioOnlyMode];
        _localLayout.layoutState = _videoMuteWhenAudioOnlyMode?NemoStreamState_Mute:NemoStreamState_Received;
    }
    
    [self _reloadCurrentPageCell];
}

- (void)onRecording {
    if (![XYSDKManager sharedInstance].isRecording) {
        [[XYSDKManager sharedInstance] checkPermissionWithCompletion:^(BOOL isRecordable, NSString * _Nonnull recordingUrl, NSString * _Nonnull errorInfo) {
            if (isRecordable == YES) {
                // 检查存储空间
                [[XYSDKManager sharedInstance] checkSorageWithCompletion:^(BOOL isStorage, NSString *errorInfo) {
                    if (isStorage == YES) {
                        [[XYSDKManager sharedInstance] startRecording];
                        self.recordingType = NemoRecordingTypeBySelf;
                        [self recordingState:YES];
                        [self showAndHideToolBar];
                    }else{
                        // 提示云录制空间不足
                        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"云录制空间不足" preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:nil];
                        [alert addAction:cancel];
                        [self presentViewController:alert animated:true completion:nil];
                    }
                }];
            }else{
                // 提示用户无录制权限
                UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"用户无录制权限" preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:nil];
                [alert addAction:cancel];
                [self presentViewController:alert animated:true completion:nil];
            }
        }];
    }else {
        [[XYSDKManager sharedInstance] stopRecording];
        self.recordingType = NemoRecordingTypeStopBySelf;
        [self recordingState:NO];
    }
}

- (void)recordingState:(BOOL)start{
    if (start) {
        _recordingView = [NemoRecordingStateView showNemoRecordingStateView];
        [self.view addSubview:_recordingView];
        [self.view insertSubview:_recordingView belowSubview:_topToolBarView];
        [_recordingView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(@20);
            if ([self _isFullScreen]) {
                make.top.equalTo(self.topToolBarView.mas_bottom).with.offset(-10);
            }else{
                make.top.equalTo(self.topToolBarView.mas_bottom).with.offset(-32);
            }
            make.left.equalTo(self.view.mas_left).with.offset(10);
        }];
        // 本地录制特殊处理
        _recordingView.recording(self.recordingType);
    }else{
        [_recordingView dismiss];
        _recordingView = nil;
    }
}

-(void)onShareScreen {
    [[XYSDKManager sharedInstance] startContentSharing:NemoShareContentType_Screen];
}

-(void)onSharePicture {
    UIImagePickerController * picker = [[UIImagePickerController alloc] init];
    picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    picker.delegate = self;
    [self presentViewController:picker animated:YES completion:nil];
}

- (void)onWhiteboard {
    [self dismissMenuView];
    if (self.whiteBoardSharingState != NemoWhiteBoardSharingStateNotSet) {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"退出白板" message:@"点击\"确定\"按钮将会使所有通话中的人退出白板功能" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:nil];
        [alertController addAction:cancel];
        UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[XYSDKManager sharedInstance] stopWhiteboard];
            [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:0];
            self.whiteBoardSharingState = NemoWhiteBoardSharingStateNotSet;
            if (self.whiteboardView) {
                [self.whiteboardView removeFromSuperview];
            }
            self.whiteboardView = nil;
            [self.bottomToolBarView updateShareItemStatus:NO];
        }];
        [alertController addAction:confirm];
        [self presentViewController:alertController animated:YES completion:nil];
    }else {
        if (self.orientation != NemoVideoOrientation_LandscapeRight) {
            [self setOrientation:NemoVideoOrientation_LandscapeRight];
        }
        if (self.whiteBoardSharingState == NemoWhiteBoardSharingStateNotSet) {
            self.whiteBoardSharingState = NemoWhiteBoardSharingStateOneself;
        }
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [[XYSDKManager sharedInstance] startWhiteboard];
            [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:0];
            _whiteboardView = [NemoWhiteboardView whiteboardView];
            _whiteboardView.whiteboardDelegate = self;
            _whiteboardView.status = NemoWhiteboardStatus_Opening;
            [self.view addSubview:_whiteboardView];
            [self.view bringSubviewToFront:_whiteboardView];
            [self.bottomToolBarView updateShareItemStatus:YES];
        });
    }
}

- (void)refreshMuteMicBtn {
    [self.bottomToolBarView updataAudioStatusWithMuteIsDisabled:_confMgmtInfo.muteIsDisabled handStatus:_isHandupNow];
    [self.bottomToolBarView updateItemWithSelectedStatus:[XYSDKManager sharedInstance].isLocalMicMuted itemType:XYBottomToolBarItemTypeAudioMute];
}

#pragma mark Action
- (void)switchCamera:(UIButton *)sender {
//    sender.selected = !sender.selected;
    if ([[XYSDKManager sharedInstance] isDefaultFrontCamera]) {
        [[XYSDKManager sharedInstance] switchCamera:
         sender.selected ? NemoDeviceType_BackCamera : NemoDeviceType_FrontCamera];
    }else{
        [[XYSDKManager sharedInstance] switchCamera:
         sender.selected ? NemoDeviceType_FrontCamera:NemoDeviceType_BackCamera];
    }
}

- (void)clickMoreEvent:(UIButton *)sender {
//    NSArray *canResponse = @[_currentPage>0?@(NO):@(YES), (_confMgmtInfo.recordIsDisabled||self.recordingType==NemoRecordingTypeByOthers)?@(NO):@(YES),@(YES),@(YES)];
    NSArray *canResponse = @[_currentPage>0?@(NO):@(YES), [NSNumber numberWithInteger:_confMgmtInfo.recordIsDisabled?NemoRecordingTypeByOthers:self.recordingType], @(YES), @(YES)];
    [self showMenuView:[MenuDataItem moreItems:canResponse] sender:sender];
}

- (void)clickShareEvent:(UIButton *)sender {
    if (self.shareView) {
        [[XYSDKManager sharedInstance] stopContentSharing];
    }else {
        NSArray *canResponse = @[_confMgmtInfo.contentIsDisabled?@(NO):@(YES), _confMgmtInfo.contentIsDisabled?@(NO):@(YES),_confMgmtInfo.whiteboardIsDisabled?@(NO):@(YES)];
        
        [self showMenuView:[MenuDataItem shareItems:canResponse] sender:sender];
    }
}


- (void)clickHostMeetingEvent {
    NSString *meetingConUrl = [[XYSDKManager sharedInstance] getMeetingControlUrl];
    WebViewController *webVC = [[WebViewController alloc] init];
    webVC.webUrl = meetingConUrl;
    [self presentViewController:webVC animated:YES completion:nil];
}

- (void)clickAudioMuteEvent {
    if (_confMgmtInfo != nil && (_confMgmtInfo.isChairmanMode && _confMgmtInfo.muteIsDisabled))
    {
        if ([XYSDKManager sharedInstance].isLocalMicMuted)
        {
            if (!_isHandupNow)
            {
                [[XYSDKManager sharedInstance] handsUp];
                _isHandupNow = YES;
            }
            else
            {
                [[XYSDKManager sharedInstance] handsDown];
                _isHandupNow = NO;
            }
        }
        else
        {
            [[XYSDKManager sharedInstance] endSpeech];
        }
    }else {
        BOOL mute = [XYSDKManager sharedInstance].isLocalMicMuted;
        [[XYSDKManager sharedInstance] setLocalMicMute:!mute];
        [self setLocalMicMute:!mute];
    }
    [self refreshMuteMicBtn];
}

- (void)setHandsUp {
    [_muteButton setTitle:@"举手发言" forState:UIControlStateNormal];
    [_muteButton setImage:[UIImage imageNamed:@"hands_up"] forState:UIControlStateNormal];
}

- (void)endSpeech {
    [_muteButton setTitle:@"结束发言" forState:UIControlStateSelected];
    [_muteButton setImage:[UIImage imageNamed:@"end_speech"] forState:UIControlStateSelected];
    
    [[XYSDKManager sharedInstance] setLocalMicMute:YES];
    [self setLocalMicMute:NO];
    _muteButton.selected = YES;
}

- (void)handsCancel{
    [_muteButton setTitle:@"取消举手" forState:UIControlStateSelected];
    [_muteButton setImage:[UIImage imageNamed:@"hands_cancel"] forState:UIControlStateSelected];
    
    [[XYSDKManager sharedInstance] setLocalMicMute:NO];
    [self setLocalMicMute:YES];
    _muteButton.selected = YES;
}

- (void)setLocalMicMute:(BOOL)mute {
    _localLayout.isAudioMute = mute;
    [self _reloadCurrentPageCell];
}

- (void)setLocalVideoMute:(BOOL)mute {
    _localLayout.layoutState = mute?NemoStreamState_Mute:NemoStreamState_Received;
//    [self.bottomToolBarView updateItemWithSelectedStatus:mute itemType:XYBottomToolBarItemTypeVideoMute];
    [self.customToolBarView updateBtnSelectedStatus:mute itemType:SEXylinkBottomToolBarActionTypeChatMode];
    [self _reloadCurrentPageCell];
}

-(void)clickVideoMuteEvent {
    BOOL mute = [XYSDKManager sharedInstance].isLocalVideoMuted;
    [[XYSDKManager sharedInstance] setLocalVideoMute:!mute];
    [self setLocalVideoMute:!mute];
    _videoMuteWhenAudioOnlyMode = !mute;
}

- (void)showMenuView:(NSArray *)items sender:(UIButton *)sender {
    if (_menu) {
        [self dismissMenuView];
    }else {
        __weak typeof(self)weakSelf = self;
        self.menu = [PulldownMenu pulldownMenuDataSource:items selected:^(NSInteger index, MenuDataItem *item) {
            switch (item.tag) {
                case 1: [weakSelf onKeyBoardInTaking]; break;
                case 2: [weakSelf onRecording]; break;
                case 3: [weakSelf onSwitchTorch]; break;
                case 4: [weakSelf onAudioMode]; break;
                case 10: [weakSelf onShareScreen]; break;
                case 11: [weakSelf onSharePicture]; break;
                case 12: [weakSelf onWhiteboard]; break;
                default:break;
            }
            [self dismissMenuView];
        } dismiss:^{
            [self dismissMenuView];
        }];
        CGFloat originX = [_bottomToolBarView left];
        if (originX + sender.frame.origin.x + sender.bounds.size.width * .5f - self.menu.bounds.size.width * .5f <= 0) {
            originX = 5;
        }else{
            originX = originX + sender.frame.origin.x + sender.bounds.size.width * .5f - self.menu.bounds.size.width * .5f;
        }
        CGFloat originY = _bottomToolBarView.frame.origin.y - 5 - self.menu.bounds.size.height;
        self.menu.frame = CGRectMake(originX, originY, self.menu.bounds.size.width, self.menu.bounds.size.height);
        [self.view addSubview:self.menu];
    }
}

- (void)showAndHideToolBar {
    [self.view bringSubviewToFront:_customToolBarView];
    [self.view bringSubviewToFront:_topToolBarView];
    [self.view bringSubviewToFront:_bottomToolBarView];
    [self.view bringSubviewToFront:_switchCameraBtn];
    if (self.customToolBarView.alpha == 0) {
        [UIView animateWithDuration:.3f animations:^{
            self.customToolBarView.alpha = 1.f;
        } completion:^(BOOL finished) {

        }];
    } else {
        [UIView animateWithDuration:.3f animations:^{
            self.customToolBarView.alpha = 0;
        } completion:^(BOOL finished) {

        }];
    }
    if (self.topToolBarView.alpha == 0) {
        [UIView animateWithDuration:.3f animations:^{
            self.topToolBarView.alpha = 1.f;
            self.bottomToolBarView.alpha = 1.f;
            [self dismissMenuView];
            if (self.whiteBoardSharingState == NemoWhiteBoardSharingStateNotSet) {
                self.switchCameraBtn.hidden = NO;
            }
        } completion:^(BOOL finished) {
            
        }];
    }else {
        [UIView animateWithDuration:.3f animations:^{
            self.topToolBarView.alpha = 0;
            self.bottomToolBarView.alpha = 0;
            [self dismissMenuView];
            self.switchCameraBtn.hidden = YES;
        } completion:^(BOOL finished) {
            
        }];
    }
}

- (void)dismissMenuView {
    if (self.menu) {
        [self.menu removeFromSuperview];
        self.menu = nil;
    }
}

- (void)showStatisticsInfo {
    UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    StatsInfoViewController *infoVC = [story instantiateViewControllerWithIdentifier:@"StatsInfoViewController"];
    [self addChildViewController:infoVC];
    [self.view addSubview:infoVC.view];
    infoVC.view.frame = self.view.bounds;
    [infoVC didMoveToParentViewController:self];
}

- (void)showStatistics {
    for (UIViewController *vc in self.childViewControllers) {
        if ([vc isKindOfClass:[StatsViewController class]]) {
            return;
        }
    }
    UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    StatsInfoViewController *infoVC = [story instantiateViewControllerWithIdentifier:@"StatsViewController"];
    [self addChildViewController:infoVC];
    [self.view addSubview:infoVC.view];
    infoVC.view.frame = self.view.bounds;
    [infoVC didMoveToParentViewController:self];
}

- (BOOL)shouldAutorotate{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    if (self.whiteBoardSharingState != NemoWhiteBoardSharingStateNotSet) {
        return UIInterfaceOrientationMaskLandscapeRight;
    }
    return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscape;
}

#pragma mark Lazy
- (SEXylinkBottomToolBarView *)customToolBarView{
    if (!_customToolBarView) {
        _customToolBarView = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(SEXylinkBottomToolBarView.class) owner:self options:nil].firstObject;
        __weak typeof(self)weakSelf = self;
        _customToolBarView.clickEventBlock = ^(UIButton * _Nonnull btn) {
            SEXylinkBottomToolBarActionType type = btn.tag;
            switch (type) {
                case SEXylinkBottomToolBarActionTypeChatMode:{
                    [weakSelf clickVideoMuteEvent];
                }
                    break;
                case SEXylinkBottomToolBarActionTypeSwitchMute:{
                    [weakSelf clickAudioMuteEvent];
                }
                    break;
                case SEXylinkBottomToolBarActionTypeSwitchCamera:{
                    [weakSelf switchCamera:btn];
                }
                    break;
                case SEXylinkBottomToolBarActionTypeHangUp:{
                    [[XYSDKManager sharedInstance] leaveMeeting];
                }
                    break;
                default:
                    break;
            }
        };
    }
    return _customToolBarView;
}

-(XYCallingBottomToolBarView *)bottomToolBarView{
    if (!_bottomToolBarView) {
        _bottomToolBarView = [XYCallingBottomToolBarView createView];
        __weak typeof(self)weakSelf = self;
        _bottomToolBarView.clickEventBlock = ^(UIButton * _Nonnull btn) {
            XYBottomToolBarItemType type = btn.tag;
            switch (type) {
                case XYBottomToolBarItemTypeMore:{
                    [weakSelf clickMoreEvent:btn];
                }
                    break;
                case XYBottomToolBarItemTypeHost:{
                    [weakSelf clickHostMeetingEvent];
                }
                    break;
                case XYBottomToolBarItemTypeShare:{
                    [weakSelf clickShareEvent:btn];
                }
                    break;
                case XYBottomToolBarItemTypeAudioMute:{
                    [weakSelf clickAudioMuteEvent];
                }
                    break;
                case XYBottomToolBarItemTypeVideoMute:{
                    btn.selected = !btn.selected;
                    [weakSelf clickVideoMuteEvent];
                }
                    break;
                default:
                    break;
            }
        };
        _bottomToolBarView.longPressEventBlock = ^{
            [weakSelf showStatistics];
        };
    }
    return _bottomToolBarView;
}

-(XYCallingTopToolBarView *)topToolBarView{
    if (!_topToolBarView) {
        _topToolBarView = [XYCallingTopToolBarView createView];
        __weak typeof(self)weakSelf = self;
        _topToolBarView.clickHangupBlock = ^{
            //挂断会议
            [[XYSDKManager sharedInstance] leaveMeeting];
        };
        _topToolBarView.tapNetworkStatusBlock = ^{
            //点击网络状态回调
            [weakSelf showStatisticsInfo];
        };
    }
    return _topToolBarView;
}

- (UICollectionViewFlowLayout *)flowLayout {
    if (!_flowLayout) {
        _flowLayout = [[UICollectionViewFlowLayout alloc] init];
        _flowLayout.itemSize = kScreen;
        _flowLayout.minimumLineSpacing = 0.000001f;
        _flowLayout.headerReferenceSize = CGSizeZero;
        _flowLayout.footerReferenceSize = CGSizeZero;
        _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    }
    return _flowLayout;
}

#pragma mark - FECC
- (BOOL)isHiddenFECC{
    NemoLayout *layout = [self _focusLayout];
    if (layout == nil) {
        return YES;
    }
    // feccOri 为0 表示没有能力操作FECC
    if (layout.feccOri == 0) {
        return YES;
    }
    if (layout.dataType == XYDataType_Device || layout.dataType == XYDataType_Bruce){
        return NO;
    }else{
        return YES;
    }
}

- (BOOL)isOnHoldFECC{
    NemoLayout *layout = [self _focusLayout];
    if (layout.layoutState == NemoStreamState_AudioOnly){
        return YES;
    }else{
        return NO;
    }
}

- (BOOL)isAudioOnly{
    NemoLayout *layout = [self _focusLayout];
    if (layout.layoutState == NemoStreamState_ReceivedAudioOnly || layout.layoutState == NemoStreamState_Mute){
        return YES;
    }else{
        return NO;
    }
}
- (unsigned int)getFeccOri{
    NemoLayout *layout = [self _focusLayout];
    return layout.feccOri;
}

- (void)refreshFeccView {
    __weak typeof(self)weakSelf = self;
    if (_feccView == nil) {
        _feccView = XYFECCView.addFECCView().inUse(^(BOOL inuse){
            if (inuse) {
                //fecc操作中回调
            }else{
                //fecc操作结束回调
            }
        }).operation(^(XYFECCOperation operation){
            [[XYSDKManager sharedInstance] farEndHardwareControlOperation:operation participantId:[[weakSelf _focusLayout] participantId]];
        }).updateFrame(YES);
        [self.view addSubview:_feccView];
    }
    if (![self isHiddenFECC] &&
        ![self isAudioOnly] &&
        _currentPage == 0 &&
        self.whiteBoardSharingState == NemoWhiteBoardSharingStateNotSet){
        _feccView.capability([self getFeccOri], [self isOnHoldFECC]);
        _feccView.hidden = NO;
    }else{
        _feccView.hidden = YES;
    }
}

#pragma mark - Whiteboard
- (void)whiteboardRemoteMessage:(id)remoteMessage type:(NemoWhiteboardOperationState)type {
    NSLog(@"%s remoteMessage -> %@", __func__, remoteMessage);
    dispatch_async(dispatch_get_main_queue(), ^{
        if (!_whiteboardView){
            NSLog(@"%s : whiteboard view still not be created", __FUNCTION__);
            return;
        }
        switch (type) {
            case 0:
            {
                if ([remoteMessage isKindOfClass:[NSString class]]) {
                    _whiteboardView.status = NemoWhiteboardStatus_Opened;
                    NSString *prop = (NSString *)remoteMessage;
                    NSArray *array = [prop componentsSeparatedByString:@"x"];
                    CGFloat aspect = 16./9.;
                    if (array.count == 2)
                    {
                        CGFloat width = [[array objectAtIndex:0] floatValue];
                        CGFloat height = [[array objectAtIndex:1] floatValue];
                        if (width>0 && height>0)
                        {
                            aspect = width/height;
                        }
                    }
                    [self getAllLineDrawn];
                }
                break;
            }
            case 1: //draw line
            {
                if (![remoteMessage isKindOfClass:[NSDictionary class]]) {
                    return;
                }
                
                NSDictionary *message = (NSDictionary *)remoteMessage;
                
                NSString *uid = [message objectForKey:@"id"];
                int seqId = [[message objectForKey:@"seq"] intValue];
                
                RemoteLineFlag flag = REMOTE_LINE_FLAG_NONE;
                NSNumber *cacheFlag = [message objectForKey:@"c"];
                if ([cacheFlag isKindOfClass:[NSNumber class]])
                {
                    flag |= REMOTE_LINE_FLAG_IS_GET_ALL;
                }
                NSArray *arr = [message objectForKey:@"p"];
                NSMutableArray *pointArray = [[NSMutableArray alloc] initWithCapacity:arr.count];
                CGFloat width = 200;
                UIColor *color = [UIColor blackColor];
                if (arr.count > 0)
                {
                    for(int i=0; i<arr.count; i++)
                    {
                        NSDictionary *pointDict = [arr objectAtIndex:i];
                        if (i==0)
                        {
                            NSString *sColor = [pointDict objectForKey:@"c"];
                            if ([sColor isKindOfClass:[NSString class]])
                            {
                                sColor = [sColor substringFromIndex:1];
                                long l = strtoul(sColor.UTF8String, 0, 16);
                                unsigned char *p = (unsigned char*)&l;
                                CGFloat red = ((CGFloat)*(p+3))/255.;
                                CGFloat green = ((CGFloat)*(p+2))/255.;
                                CGFloat blue = ((CGFloat)*(p+1))/255.;
                                CGFloat alpha = ((CGFloat)*p)/255.;
                                color = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
                                flag |= REMOTE_LINE_FLAG_IS_START;
                            }
                            
                            id oWidth = [pointDict objectForKey:@"w"];
                            if ([oWidth isKindOfClass:[NSNumber class]])
                            {
                                width = [oWidth floatValue];
                            }
                        }
                        
                        if (i==arr.count-1)
                        {
                            id oWidth = [pointDict objectForKey:@"w"];
                            if ([oWidth isKindOfClass:[NSNumber class]])
                            {
                                if ([oWidth floatValue]==0)
                                {
                                    flag |= REMOTE_LINE_FLAG_IS_FINISH;
                                }
                            }
                        }
                        
                        CGPoint point = CGPointMake([[pointDict objectForKey:@"x"] floatValue],
                                                    [[pointDict objectForKey:@"y"] floatValue]);
                        
                        [pointArray addObject:[NSValue valueWithCGPoint:point]];
                        
                    }
                }
                
                NSString *ownUid = [NSString stringWithFormat:@"%ld@SOFT",
                                    [XYSDKManager sharedInstance].user.userId];
                if (!(flag & REMOTE_LINE_FLAG_IS_GET_ALL) && [uid isEqualToString:ownUid])
                {
                    flag |= REMOTE_LINE_FLAG_SAVE_ONLY;
                }
                
                [_whiteboardView drawLineWithSequenceId:seqId
                                                  color:color
                                                  width:width
                                                 points:pointArray
                                               lineFlag:flag];
                
                break;
            }
            case 2: //clear all line
            {
                [_whiteboardView clear];
                break;
            }
            case 3: // get all line
            {
                break;
            }
            case 4: // undo
            {
                int seqId = [remoteMessage intValue];
                [_whiteboardView undoWithSeqId:seqId];
                break;
            }
            case 5: // redo
            {
                int seqId = [remoteMessage intValue];
                [_whiteboardView redoWithSeqId:seqId];
                break;
            }
            default:
                break;
        }
    });
}

- (void)getAllLineDrawn {
    //get all exist lines
    [[XYSDKManager sharedInstance] sendWhiteboardMsg:nil type:NemoWhiteboardOperation_All];
    [_whiteboardView clear];
}

- (void)didDrawLineInWhiteboard:(NemoWhiteboardView*)wbView
                          Color:(UIColor*)color
                          width:(CGFloat)width
                         points:(NSArray*)pointArray
                        isStart:(BOOL)isStart
                       isFinish:(BOOL)isFinish{
    NSMutableArray *marray = [[NSMutableArray alloc] initWithCapacity:pointArray.count];
    for (int i=0 ;i<pointArray.count; i++)
    {
        NSDictionary *pointDict = nil;
        CGPoint point = [[pointArray objectAtIndex:i] CGPointValue];
        if (isStart && i==0)
        {
            CGFloat red, green, blue, alpha;
            [color getRed:&red green:&green blue:&blue alpha:&alpha];
            NSString *sColor = [NSString stringWithFormat:@"#%02x%02x%02x%02x",
                                (unsigned char)(red*255),
                                (unsigned char)(green*255),
                                (unsigned char)(blue*255),
                                (unsigned char)(alpha*255)];
            pointDict = @{@"x":@(point.x), @"y":@(point.y), @"c":sColor, @"w":@(width)};
        }
        else if(isFinish && i==pointArray.count-1)
        {
            pointDict = @{@"x":@(point.x), @"y":@(point.y), @"w":@0};
        }
        else
        {
            pointDict = @{@"x":@(point.x), @"y":@(point.y)};
        }
        
        [marray addObject:pointDict];
    }
    [[XYSDKManager sharedInstance] sendWhiteboardMsg:marray type:NemoWhiteboardOperation_Draw];
}

- (void)didClearedInWhiteboard:(NemoWhiteboardView*)wbView{
    [[XYSDKManager sharedInstance] sendWhiteboardMsg:nil type:NemoWhiteboardOperation_Clear];
}

- (void)didUndoInWhiteboard:(NemoWhiteboardView*)wbView seqId:(int)seqId{
    NSString *seqIdStr = [NSString stringWithFormat:@"%d",seqId];
    [[XYSDKManager sharedInstance] sendWhiteboardMsg:seqIdStr type:NemoWhiteboardOperation_Undo];
}

- (void)didRedoInWhiteboard:(NemoWhiteboardView*)wbView seqId:(int)seqId{
    NSString *seqIdStr = [NSString stringWithFormat:@"%d",seqId];
    [[XYSDKManager sharedInstance] sendWhiteboardMsg:seqIdStr type:NemoWhiteboardOperation_Redo];
}

#pragma mark - UICollectionView
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _allPage;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 0) {
        XYVideoContainerCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AsymmetryrCell" forIndexPath:indexPath];
        cell.localLayout = _localLayout;
        return cell;
    }
    XYVideoContainerCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SymmetryrCell" forIndexPath:indexPath];
    cell.localLayout = _localLayout;
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
    
    if (indexPath.row < 2  && _rosters.contentSenderPid == 0) {
        return;
    }
    for (NemoLayout *layout in [_dataSource objectForKey:@(indexPath.row)]) {
        if (layout != _localLayout) {
            layout.layoutState = NemoStreamState_Requesting;
        }
    }
    XYVideoContainerCell *containerCell = (XYVideoContainerCell *)cell;
    [containerCell updateVideos:[_dataSource objectForKey:@(indexPath.row)] index:indexPath.row activeSpeakerId:_rosters.activeSpeakerPid];
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [collectionView deselectItemAtIndexPath:indexPath animated:NO];
    [self showAndHideToolBar];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self dismissMenuView];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger indexPage = scrollView.contentOffset.x/kScreen.width;
    self.pageControl.currentPage = indexPage;
    if (_currentPage == indexPage) {
        return;
    }
    if ((_currentPage == 0 && indexPage == 1) ||
        (_currentPage == 1 && indexPage == 0)) {
        //前两页内滑动
        if (_rosters.contentSenderPid == 0) {
            //没有content
            if (_allPage > 2) {
                if (_currentPage == 0 && indexPage == 1) {
                    //从第1页到第2页，不需要请流
                    _currentPage = indexPage;
                    [self _reloadCurrentPageCell];
                }else {
                    //大于2页，则从第2页（1+5）滑动到第1页（1+6）需要重新请流，否则第一页会少一路
                    _currentPage = indexPage;
                    if (_rosters) {
                        [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:indexPage];
                    }
                }
            }else {
                //小于2页，不请流
                _currentPage = indexPage;
                [self _reloadCurrentPageCell];
            }
        }else {
         //有content
            _currentPage = indexPage;
            if (_rosters) {
                [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:indexPage];
            }
        }
    }else {
        //其他页面
        _currentPage = indexPage;
        if (_rosters) {
            [[XYLayoutManager sharedInstance] customLayout:_rosters indexPage:indexPage];
        }
    }
}

#pragma mark - UIImagePickerControllerDelegate UINavigationControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    [self dismissViewControllerAnimated:YES completion:nil];
    self.shareImage = image;
    [[XYSDKManager sharedInstance] startContentSharing:NemoShareContentType_Image];
    XYRTCContent *content = [[XYRTCContent alloc] init];
    content.type = NemoShareContentType_Image;
    content.image = image;
    content.imageFrameRate = 5;
    [[XYSDKManager sharedInstance] sendContentMsg:content];
    
    [self dismissMenuView];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
